package br.com.petsis.utilitarios;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.List;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

import br.com.petsis.vo.ValoresGraficosVO;

public class UtilGraficos{

	public static final Integer TIPO_EIXO_X_MESES = 1;
	public static final Integer TIPO_EIXO_X_DIAS_SEMANA = 2;
	
	public static byte[] gerarGraficoDeLinhas(String titulo, List<ValoresGraficosVO> valores, Integer width, Integer height) { 
		CategoryDataset dataset = createDataSet(valores, "");
		final JFreeChart chart = createLineChart(dataset, titulo);
		try { 
			BufferedImage img = chart.createBufferedImage(width, height);
			byte[] imgByte = ChartUtilities.encodeAsPNG(img);
			return imgByte;
//			ChartUtilities.saveChartAsJPEG(new File("C:\\chartLinha.jpg"), chart, 500,300); 
		} catch (IOException e) { 
			// TODO Auto-generated catch block 
			e.printStackTrace(); 
		} 
		return null;
	} 
	
	public static byte[] gerarGraficoDeBarras(String titulo, List<ValoresGraficosVO> valores, Integer width, Integer height) { 
		CategoryDataset dataset = createDataSetBarChart(valores, "");
		final JFreeChart chart = createBarChart(dataset, titulo);
		try { 
			BufferedImage img = chart.createBufferedImage(width, height);
			byte[] imgByte = ChartUtilities.encodeAsPNG(img);
			return imgByte;
//			ChartUtilities.saveChartAsJPEG(new File("C:\\chartLinha.jpg"), chart, 500,300); 
		} catch (IOException e) { 
			// TODO Auto-generated catch block 
			e.printStackTrace(); 
		} 
		return null;
	} 

	private static CategoryDataset createDataSet(List<ValoresGraficosVO> valores, String tituloEixoX){ 
	
		final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		
		for(ValoresGraficosVO v : valores){
			dataset.addValue(v.getValor(), tituloEixoX, v.getLabel());
		}
	
		return dataset; 
	}
	
	private static CategoryDataset createDataSetBarChart(List<ValoresGraficosVO> valores, String tituloEixoX){ 
		
		final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		
		for(ValoresGraficosVO v : valores){
			dataset.addValue(v.getValor(), v.getLabel(), v.getLabel());
		}
		
		return dataset; 
	} 

	private static JFreeChart createLineChart( final CategoryDataset dataset, String tituloGrafico ){ 

		final JFreeChart chart = ChartFactory.createLineChart( 
		tituloGrafico, 
		"", 
		"", 
		dataset, 
		PlotOrientation.VERTICAL, 
		false, 
		false, 
		true); 


		// Definindo cor de fundo do gráfico 
		chart.setBackgroundPaint( Color.white ); 
	
		// Pegando a plotagem do gráfico para modificar o gráfico 
		final CategoryPlot plot = (CategoryPlot) chart.getPlot(); 
		plot.setBackgroundPaint( Color.decode( "#CCFF00" ) ); 
	
		// Definindo valores no eixo y 
//		plot.getRangeAxis().setRange(0, 130); 
	
		// Definindo a escala do eixo y do gráfico 
		NumberAxis numberAxis = (NumberAxis)plot.getRangeAxis(); 
		numberAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); 
		numberAxis.setAutoRangeIncludesZero(false); 
//		numberAxis.setTickUnit(new NumberTickUnit(10)); 
//		numberAxis.setRange(0, 110); 
	
		// Mudando a cor da linha do gráfico 
		CategoryItemRenderer categoryitemrenderer = plot.getRenderer(); 
		categoryitemrenderer.setSeriesPaint(0, Color.decode("#000066")); 
	
		// Mudando a espessura da linha do gráfico 
		final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer(); 
		renderer.setSeriesStroke( 0, 
		new BasicStroke(0.9f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 
		0.0f, new float[] {1.0f, 1.0f}, 0.0f )); 
	
		// Exibindo os valores nas linhas do gráfico 
		renderer.setSeriesItemLabelsVisible(0, true); 
		StandardCategoryItemLabelGenerator labelGenerator = 
			new StandardCategoryItemLabelGenerator("{2}",new DecimalFormat("#,##0.00##")); 
		renderer.setSeriesItemLabelPaint(0, Color.decode("#000066")); 
		renderer.setSeriesItemLabelFont(0, new Font( "SansSerif", Font.PLAIN, 10)); 
		renderer.setSeriesItemLabelGenerator(0, labelGenerator); 
	
		// Exibindo a gráfico princiapl 
		renderer.setSeriesShapesVisible(0, true); 
	
		// Definindo as cores de fundo do gráfico conforme eixo y 
		/*final IntervalMarker target = new IntervalMarker(0.0, 80.0); 
		target.setLabel(""); 
		target.setLabelFont(new Font("SansSerif", Font.ITALIC, 11)); 
		target.setLabelAnchor(RectangleAnchor.LEFT); 
		target.setLabelTextAnchor(TextAnchor.CENTER_LEFT); 
		target.setPaint( Color.decode( "#FFD2D2" ) ); 
		target.setOutlinePaint( Color.BLACK ); 
		target.setOutlineStroke( new BasicStroke(1.1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 
		0.0f, new float[] {1.0f, 1.0f}, 0.0f ) ) ; 
		plot.addRangeMarker(target, Layer.BACKGROUND); 
	
		final IntervalMarker target1 = new IntervalMarker(80.0, 90.0); 
		target1.setLabel(""); 
		target1.setLabelFont(new Font("SansSerif", Font.ITALIC, 11)); 
		target1.setLabelAnchor(RectangleAnchor.LEFT); 
		target1.setLabelTextAnchor(TextAnchor.CENTER_LEFT); 
		target1.setPaint( Color.decode( "#FFFFD2" ) ); 
		target1.setOutlinePaint( Color.BLACK ); 
		target1.setOutlineStroke( new BasicStroke(1.1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 
		0.0f, new float[] {1.0f, 1.0f}, 0.0f ) ) ; 
		plot.addRangeMarker(target1, Layer.BACKGROUND); 
	
		final IntervalMarker target2 = new IntervalMarker(90.0, 120.0); 
		target2.setLabel(""); 
		target2.setLabelFont(new Font("SansSerif", Font.ITALIC, 11)); 
		target2.setLabelAnchor(RectangleAnchor.LEFT); 
		target2.setLabelTextAnchor(TextAnchor.CENTER_LEFT); 
		target2.setPaint( Color.decode( "#D2FFD2" ) ); 
		target2.setOutlinePaint( Color.BLACK ); 
		target2.setOutlineStroke( new BasicStroke(1.1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 
		0.0f, new float[] {1.0f, 1.0f}, 0.0f ) ) ; 
		plot.addRangeMarker(target2, Layer.BACKGROUND); 
	
		final IntervalMarker target3 = new IntervalMarker(120.0, 240.0); 
		target3.setLabel(""); 
		target3.setLabelFont(new Font("SansSerif", Font.ITALIC, 11)); 
		target3.setLabelAnchor(RectangleAnchor.LEFT); 
		target3.setLabelTextAnchor(TextAnchor.CENTER_LEFT); 
		target3.setPaint( Color.decode( "#FFFFD2" ) ); 
		target3.setOutlinePaint( Color.BLACK ); 
		target3.setOutlineStroke( new BasicStroke(1.1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 
		0.0f, new float[] {1.0f, 1.0f}, 0.0f ) ) ; 
	
		plot.addRangeMarker(target3, Layer.BACKGROUND); */
	
	
		return chart; 

	} 
	
    /**
     * Creates a sample chart.
     * 
     * @param dataset  the dataset.
     * 
     * @return The chart.
     */
    private static JFreeChart createBarChart(final CategoryDataset dataset, String titulo) {
        
        // create the chart...
        final JFreeChart chart = ChartFactory.createBarChart(
            titulo,         // chart title
            "",               // domain axis label
            "",                  // range axis label
            dataset,                  // data
            PlotOrientation.VERTICAL, // orientation
            true,                     // include legend
            true,                     // tooltips?
            false                     // URLs?
        );

        // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...

        // set the background color for the chart...
        chart.setBackgroundPaint(Color.white);

        // get a reference to the plot for further customisation...
        final CategoryPlot plot = chart.getCategoryPlot();
        plot.setBackgroundPaint(Color.decode( "#CCFF00" ));
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);

        // set the range axis to display integers only...
        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

        // disable bar outlines...
        final BarRenderer renderer = (BarRenderer) plot.getRenderer();
        renderer.setDrawBarOutline(false);
        
        // set up gradient paints for series...
        final GradientPaint gp0 = new GradientPaint(
            0.0f, 0.0f, Color.blue, 
            0.0f, 0.0f, Color.blue
        );
        final GradientPaint gp1 = new GradientPaint(
            0.0f, 0.0f, Color.green, 
            0.0f, 0.0f, Color.green
        );
        final GradientPaint gp2 = new GradientPaint(
            0.0f, 0.0f, Color.red, 
            0.0f, 0.0f, Color.red
        );
        final GradientPaint gp3 = new GradientPaint(
        		0.0f, 0.0f, Color.decode( "#DAA520" ), 
        		0.0f, 0.0f, Color.decode( "#DAA520" )
        );
        final GradientPaint gp4 = new GradientPaint(
        		0.0f, 0.0f, Color.decode( "#B22222" ), 
        		0.0f, 0.0f, Color.decode( "#B22222" )
        );
        final GradientPaint gp5 = new GradientPaint(
        		0.0f, 0.0f, Color.decode( "#FF00FF" ), 
        		0.0f, 0.0f, Color.decode( "#FF00FF" )
        );
        final GradientPaint gp6 = new GradientPaint(
        		0.0f, 0.0f, Color.decode( "#4876FF" ), 
        		0.0f, 0.0f, Color.decode( "#4876FF" )
        );
        final GradientPaint gp7 = new GradientPaint(
        		0.0f, 0.0f, Color.decode( "#8B4726" ), 
        		0.0f, 0.0f, Color.decode( "#8B4726" )
        );
        final GradientPaint gp8 = new GradientPaint(
        		0.0f, 0.0f, Color.decode( "#FFFAFA" ), 
        		0.0f, 0.0f, Color.decode( "#FFFAFA" )
        );
        renderer.setSeriesPaint(0, gp0);
        renderer.setSeriesPaint(1, gp1);
        renderer.setSeriesPaint(2, gp2);
        renderer.setSeriesPaint(3, gp3);
        renderer.setSeriesPaint(4, gp4);
        renderer.setSeriesPaint(5, gp5);
        renderer.setSeriesPaint(6, gp6);
        renderer.setSeriesPaint(7, gp7);
        renderer.setSeriesPaint(8, gp8);
        
        // Exibindo os valores nas linhas do gráfico 
		StandardCategoryItemLabelGenerator labelGenerator = 
			new StandardCategoryItemLabelGenerator("{2}",new DecimalFormat("#,##0.00##")); 
		
		renderer.setSeriesItemLabelsVisible(0, true); 
		renderer.setSeriesItemLabelPaint(0, Color.decode("#000066")); 
		renderer.setSeriesItemLabelFont(0, new Font( "SansSerif", Font.PLAIN, 10)); 
		renderer.setSeriesItemLabelGenerator(0, labelGenerator); 

		renderer.setSeriesItemLabelsVisible(1, true); 
		renderer.setSeriesItemLabelPaint(1, Color.decode("#000066")); 
		renderer.setSeriesItemLabelFont(1, new Font( "SansSerif", Font.PLAIN, 10)); 
		renderer.setSeriesItemLabelGenerator(1, labelGenerator); 
		
		renderer.setSeriesItemLabelsVisible(2, true); 
		renderer.setSeriesItemLabelPaint(2, Color.decode("#000066")); 
		renderer.setSeriesItemLabelFont(2, new Font( "SansSerif", Font.PLAIN, 10)); 
		renderer.setSeriesItemLabelGenerator(2, labelGenerator); 
		
		renderer.setSeriesItemLabelsVisible(3, true); 
		renderer.setSeriesItemLabelPaint(3, Color.decode("#000066")); 
		renderer.setSeriesItemLabelFont(3, new Font( "SansSerif", Font.PLAIN, 10)); 
		renderer.setSeriesItemLabelGenerator(3, labelGenerator); 
		
		renderer.setSeriesItemLabelsVisible(4, true); 
		renderer.setSeriesItemLabelPaint(4, Color.decode("#000066")); 
		renderer.setSeriesItemLabelFont(4, new Font( "SansSerif", Font.PLAIN, 10)); 
		renderer.setSeriesItemLabelGenerator(4, labelGenerator); 
		
		renderer.setSeriesItemLabelsVisible(5, true); 
		renderer.setSeriesItemLabelPaint(5, Color.decode("#000066")); 
		renderer.setSeriesItemLabelFont(5, new Font( "SansSerif", Font.PLAIN, 10)); 
		renderer.setSeriesItemLabelGenerator(5, labelGenerator); 
		
		renderer.setSeriesItemLabelsVisible(6, true); 
		renderer.setSeriesItemLabelPaint(6, Color.decode("#000066")); 
		renderer.setSeriesItemLabelFont(6, new Font( "SansSerif", Font.PLAIN, 10)); 
		renderer.setSeriesItemLabelGenerator(6, labelGenerator); 
		
		renderer.setSeriesItemLabelsVisible(7, true); 
		renderer.setSeriesItemLabelPaint(7, Color.decode("#000066")); 
		renderer.setSeriesItemLabelFont(7, new Font( "SansSerif", Font.PLAIN, 10)); 
		renderer.setSeriesItemLabelGenerator(7, labelGenerator); 
		
		renderer.setSeriesItemLabelsVisible(8, true); 
		renderer.setSeriesItemLabelPaint(8, Color.decode("#000066")); 
		renderer.setSeriesItemLabelFont(8, new Font( "SansSerif", Font.PLAIN, 10)); 
		renderer.setSeriesItemLabelGenerator(8, labelGenerator); 
		
        final CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setVisible(false);
        domainAxis.setCategoryLabelPositions(
            CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 6.0)
        );
        // OPTIONAL CUSTOMISATION COMPLETED.
        
        return chart;
        
    }
}
